package com.qianyu.core.service.impl;

import cn.hutool.core.util.ObjUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qianyu.core.api.ApiCommon;
import com.qianyu.core.entity.base.BaseIdDto;
import com.qianyu.core.entity.bean.*;
import com.qianyu.core.entity.dto.LinkDto;
import com.qianyu.core.enumerate.ResultEnum;
import com.qianyu.core.exception.CustomerException;
import com.qianyu.core.helper.LoginHelper;
import com.qianyu.core.mapper.LinkMapper;
import com.qianyu.core.service.GameAreaService;
import com.qianyu.core.service.GameService;
import com.qianyu.core.service.LinkActService;
import com.qianyu.core.service.LinkService;
import com.qianyu.core.util.MD5Util;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Service
@RequiredArgsConstructor
public class LinkServiceImpl extends ServiceImpl<LinkMapper, Link> implements LinkService {


    private final ApiCommon apiCommon;

    private final LinkActService linkActService;

    private final GameService gameService;

    private final GameAreaService gameAreaService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addLinkActTask(LinkDto.LinkTaskDto dto) {
        User user = LoginHelper.getLoginUser();
        validatedAct(dto.getUrl(), user.getId());

        List<LinkAct> list = new ArrayList<>();
        List<GameArea> areas = new ArrayList<>();
        JSONObject json = apiCommon.fetchQBActivityList(dto.getUrl());
        //游戏活动
        JSONArray jsonArray = json.getJSONArray("activityInfo");
        //游戏区服
        JSONObject areaInfo = json.getJSONObject("selectAreaInfo");
        //区服名称
        JSONObject jsonObject = areaInfo.getJSONObject("serverList").getJSONObject("and");
        Set<String> areaNames = jsonObject.keySet();
        Link link = new Link() {{
            setAppid(json.getString("appId"));
            setAppName(json.getString("appName"));
            setGame(json.getString("game"));
            setToken(json.getString("token"));
            setRemark(dto.getRemark());
            setActLength(jsonArray.size());
            setUserId(user.getId());
            setTitle(getAppName() + "-活动链接");
            setRoleId(Integer.valueOf(areaInfo.getString("roleId")));
            setUrlMd5(MD5Util.md5(dto.getUrl()));
            setUrl(dto.getUrl());
            setCreateUser(user.getNickname());
        }};
        save(link);

        for (Object o : jsonArray) {
            JSONObject object = (JSONObject) o;
            LinkAct act = new LinkAct() {{
                setActName(object.getString("actName"));
                setActId(Integer.valueOf(object.getString("actid")));
                setIsSso(object.getBoolean("isSSOSend") ? 1 : 0);
                setUserId(user.getId());
                setLinkId(link.getId());
                setAppid(link.getAppid());
            }};

            list.add(act);
        }
        linkActService.saveBatch(list);

        Game game = new Game() {{
            setName(link.getAppName());
            setCode(link.getGame());
            setAppid(link.getAppid());
        }};

        gameService.saveGame(game);

        for (String s : areaNames) {
            GameArea area = new GameArea() {{
                setArea(s);
                setAreaId(jsonObject.getInteger(s));
                setType(0);
                setAppid(link.getAppid());
            }};
            areas.add(area);

        }
        gameAreaService.saveBatch(areas);

        return true;
    }


    @Override
    public List<Link> listLink() {
        return list(Wrappers.<Link>lambdaQuery().eq(Link::getUserId, LoginHelper.getUserId()));
    }

    @Override
    public List<LinkAct> listActByLinkId(BaseIdDto dto) {
        return linkActService.list(Wrappers.<LinkAct>lambdaQuery().eq(LinkAct::getLinkId, dto.getId()));
    }


    private void validatedAct(String url, Long userId) {
        LambdaQueryWrapper<Link> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Link::getUserId, userId).eq(Link::getUrl, url);
        Link link = baseMapper.selectOne(wrapper);
        if (ObjUtil.isNotEmpty(link)) {
            throw new CustomerException(ResultEnum.ACT_LINK_EXIST);
        }
    }
}
